package com.zhang.learn.service.strategy.kpi;


import com.zhang.learn.service.strategy.kpi.dto.BalanceKPIContext;
import com.zhang.learn.service.strategy.kpi.dto.KpiCalculatorContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @Author: zxl
 * @Date: 2024/12/6 17:52
 */
@Service
@Slf4j
public class MonthKpiCalculator extends AbstractKpiCalculator {

    /**
     * 说明策略的类型
     */
    @Override
    protected ComputedType computedKPITypeEnum() {
        return ComputedType.MONTH;
    }

    /**
     * 月度KPI计算策略的具体实现逻辑
     * @param contextList
     */
    @Override
    protected void doComputedKPI(List<KpiCalculatorContext> contextList) {
        ExecutorService executor = Executors.newFixedThreadPool(5);
        // 使用CompletableFuture 进行任务编排 多线程执行
        List<CompletableFuture<Integer>> futures = contextList.stream()
                .map(context -> CompletableFuture.supplyAsync(() -> {
                    int result = super.balanceKPIComputed(
                            BalanceKPIContext.builder()
                                    .weight(context.getMouthWeight())
                                    .build()
                    );
                    // 使用属性拷贝，把context 中的数据 拷贝到  balanceKPIComputed 这个方法的返回值中去 作为返回值
                      BeanUtils.copyProperties(context, result);
                    return result;
                }, executor))
                .collect(Collectors.toList());

        // 等待所有公司的KPI计算完成
        CompletableFuture<Void> all = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));

        // 收集结果
        List<Integer> resultList = all.thenApply(v ->
                futures.stream().map(CompletableFuture::join).collect(Collectors.toList())
        ).join();
        // return resultList;
    }

}
